home *** CD-ROM | disk | FTP | other *** search
- ifdef DOCUMENTATION
- ; ******************************* DOCZ Header ********************************
- .MODULE strmcpy
- .LIBRARY csub
- .TYPE function
- .APPLICATION string
- .SYSTEM msdos
- .SYSTEM vms
- .SYSTEM unix
- .AUTHOR Software Toolz
- .DESCRIPTION
- Perform a bounded string copy and produce a NULL terminated string
- .ARGUMENTS
- char *strmcpy(dest,source,maxchar)
- char *dest, /* (w) destination string */
- *source; /* (r) source string */
- int maxchar; /* (r) maximum characters to copy */
- .NARRATIVE
- Strmcpy behaves exactly like strncpy() except that the destination string
- is always NULL-terminated. The "maxchar" argument specifies the size of
- the destination array (NOT including the NULL). If the length of the source
- string exceeds "maxchar" then the last character copied to the destination
- string will be a NULL character.
- .RETURNS
- The address of the destination string.
- .COMMENTS
- This function eliminates a common C pitfall caused by strncpy() producing
- un-terminated strings.
- .LANGUAGE
- VMS, MSDOS: Assembly; UNIX: C
- .FIXES 4/15/88
- Changed documentation to match performance of function.
- Used to be: The "maxchar" argument specifies the size of the destination
- array (including the NULL).
- Is now: The "maxchar" argument specifies the size of the destination
- array (NOT including the NULL).
- .ENDOC END DOCUMENTATION
- ; ****************************************************************************
- endif
-
- INCLUDE \HEADER\C.MAC
-
- SFRAME STRUC
- SAV_DI DW ?
- SAV_SI DW ?
- SAV_CX DW ?
- SAV_ES DW ?
- REG_BP DW ? ; base pointer to be pushed
- RTN_ADD DW ? ; offset of return address
- DEST DW ? ; destination string address
- SOURCE DW ? ; source string address
- MAXCHAR DW ? ; character count value
- SFRAME ENDS
-
- ; ****************************************************************************
- ; code
- ; ****************************************************************************
- PSEG ; begin program section
- CFEXT strlen
-
- CFUN strmcpy
-
- PUSH BP
- PUSH ES
- PUSH CX
- PUSH SI
- PUSH DI
- MOV BP,SP
- MOV AX,DS
- MOV ES,AX
- CLD
-
- PUSH [BP].SOURCE
- CCALL strlen ; get length of source string
- MOV SP,BP
- MOV CX,[BP].MAXCHAR
- INC AX ; add space for NULL
- CMP AX,CX
- JG SCPY ; then truncate
- MOV CX,AX ; use length as loop counter
- SCPY:
- MOV SI,[BP].SOURCE
- MOV DI,[BP].DEST
- REP MOVSB ; do the copy
- XOR AX,AX ; load NULL
- STOSB
- FINI:
- MOV AX,[BP].DEST ; copy destination string address
- POP DI
- POP SI
- POP CX
- POP ES
- POP BP
- RET
-
- CFEND strmcpy
-
- ENDPS ; end program section
-
- END
-
- /*****************************************************************************
- C test program
- *****************************************************************************/
- #include <stdio.h>
- #include "csub.h"
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char buff[128];
-
- if (argc == 3)
- {
- strmcpy(buff,argv[1],atoi(argv[2]));
- printf("input string length = %d\r\n",strlen(argv[1]));
- printf("input string = (%s)\r\n",argv[1]);
- printf("maximum characters = %d\r\n",atoi(argv[2]));
- printf("result = (%s)\r\n",buff);
- }
- else
- puts("STRMCPY [string] [max. characters]");
- }
-
- ; ****************************************************************************
- ; End STRMCPY.ASM
- ; ****************************************************************************
-